/**
 * @author ZhangHuihua@msn.com
 * 
 */

var DWZ = {
	// sbar: show sidebar
	keyCode: {
		ENTER: 13, ESC: 27, END: 35, HOME: 36,
		SHIFT: 16, TAB: 9,
		LEFT: 37, RIGHT: 39, UP: 38, DOWN: 40,
		DELETE: 46, BACKSPACE:8
	},
	statusCode: {ok:200, error:300, timeout:301,warning:302},
	ui:{sbar:true},
	frag:{}, //page fragment
	pop:{},	//pop
	_msg:{}, //alert message
	_set:{
		loginUrl:"", //session timeout
		loginTitle:"", //if loginTitle open a login dialog
		debug:false
	},
	msg:function(key, args){
		var _format = function(str,args) {
			args = args || [];
			var result = str
			for (var i = 0; i < args.length; i++){
				result = result.replace(new RegExp("\\{" + i + "\\}", "g"), args[i]);
			}
			return result;
		}
		return _format(this._msg[key], args);
	},
	debug:function(msg){
		if (this._set.debug) alert(msg);
	},
	loadLogin: function(){
		if ($.pdialog && DWZ._set.loginTitle) {
			$.pdialog.open(DWZ._set.loginUrl, "login", DWZ._set.loginTitle, {mask:true,width:400,height:200});
		} else {
			window.location = DWZ._set.loginUrl;
		}
	},
	login:function(callback){
		var dialog=$.pdialog.getCurrent();
		if(dialog && dialog.length>0 && dialog.data("id")=="login" && !dialog.is(":hidden")){
			return;
		}
					
		var isLoginTimeout=DWZ.user.isLogin();
		
		if(!isLoginTimeout){
			location.href="login.html";
			return;
		}
		
		$.pdialog.open(DWZ._set.loginUrl, "login", isLoginTimeout?"登录超时，请重新登录":"管理员登录", {maxable:false,closeable:false,mask:true,width:400,height:200},function(user){
			DWZ.user.role=user.role;
			$.cookie("user_id",DWZ.user.userid=user.user_id);
			$.cookie("username",DWZ.user.username=user.username,{expires:20});
			$.cookie("role",user.role.role);
			$.cookie("rolename",user.role.name);
			$.cookie("is_login",true);
						//expires
			if(!isLoginTimeout){
				location.reload();
				return;
			};//$("#layout").show();
			initAccount();
			if($.isFunction(callback))callback();
			//initUI();
		});
	},
	logout:function(){
		DWZ.get("/account/logout",function(json){
			$.cookie("user_id",null);
			$.cookie("is_login",null);
			//location.reload();
			location.href="login.html";
		})
	},
	user:{
		userId:$.cookie("user_id"),
		username:$.cookie("username"),
		role:$.cookie("role"),
		rolename:$.cookie("rolename"),
		isLogin:function(){
			return $.cookie("is_login");
		}
	},
	jsonEval:function (json) {
		try{
			return eval('(' + json + ')');
		} catch (e){
			return {};
		}
	},
	ajaxError:function (xhr, ajaxOptions, thrownError){
		if (alertMsg) {
			alertMsg.error("<p>Http status: " + xhr.status + " " + xhr.statusText + "</p>");
		}
		DWZ.debug("Http status: " + xhr.status + " " + xhr.statusText + "\najaxOptions: " + ajaxOptions + "\nthrownError:"+thrownError);
		DWZ.debug(xhr.responseText);
	},
	ajaxDone:function (json){
		if(json.statusCode == DWZ.statusCode.error) {
			if(json.message && alertMsg) alertMsg.error(json.message);
//		} else if (json.statusCode == DWZ.statusCode.timeout) {
//			if(json.message && alertMsg) alertMsg.error(json.message, {okCall:DWZ.loadLogin});
//			else loadLogin();
		} else {
			if(json.message && alertMsg) alertMsg.correct(json.message);
		};
	},
	init: function(pageFrag, options){
		var op = $.extend({
				loginUrl:"login.html", loginTitle:null, callback:null, debug:false, 
				statusCode:{}
			}, options);
		this._set.loginUrl = op.loginUrl;
		this._set.loginTitle = op.loginTitle;
		this._set.debug = op.debug;
		$.extend(DWZ.statusCode, op.statusCode);
		
		jQuery.ajax({
			type:'GET',
			url:pageFrag,
			dataType:'xml',
			timeout: 50000,
			cache: false,
			error: function(xhr){
				alert('Error loading XML document: ' + pageFrag + "\nHttp status: " + xhr.status + " " + xhr.statusText);
			}, 
			success: function(xml){
				$(xml).find("_PAGE_").each(function(){
					var pageId = $(this).attr("id");
					if (pageId) DWZ.frag[pageId] = $(this).text();
				});
				
				$(xml).find("_MSG_").each(function(){
					var id = $(this).attr("id");
					if (id) DWZ._msg[id] = $(this).text();
				});
				
				if (jQuery.isFunction(op.callback)) op.callback();
			}
		});
	},
	param:function(data,params){
		function toMap(str,o){
			if(!str) return {};
			o=o||{};
			var a=str.split("&");
			$.each(a,function(i,value){
				var v=value.split("=");
				if(v.length>1)
					o[v[0]]=v[1]==null||v[1]==undefined||v[1]=="undefined"?"":v[1];
			})
		}
		var o=data&&typeof(data)=="object"?data:toMap(data);
		if(params) toMap(params,o);
		return o;
	},
	//重新加载ajax,chenxiang
	reload:function(){
		if(!top.ajaxList) return;
		//重新发送请求
		for(var s in top.ajaxList){
			var req=top.ajaxList.splice(0,1);
			DWZ.ajax(req[0],true);
		}
		
		DWZ.clearAjaxList();
	},
	clearAjaxList:function(){
		//请求完后删除
		if(!top.ajaxList) return;
		try{
			for(var i=0,l=top.ajaxList.length;i<l;i++){
				top.ajaxList.shift();
			}
		}catch(e){
			//do nothing
		}
		top.ajaxList=null;
	},
	toServiceUrl:function(url){
		var root="/services";
		url=root+(url.indexOf("/")==0?url:"/"+url);
		return url+(url.indexOf("?")>0?"&":"?")+"_t="+(new Date().getTime());
	},
	showbg:function(){
		DWZ.ajaxbgshow=setTimeout(function(){
			clearTimeout(DWZ.ajaxbgshow);
			DWZ.ajaxbg.show();
		},0);
	},
	hidebg:function(){
		DWZ.ajaxbghide=setTimeout(function(){
			clearTimeout(DWZ.ajaxbghide);
			DWZ.ajaxbg.hide();
		},0);
	},
	ajax:function(s,isReload){
		if(!s) return;
		var ajaxTime=setTimeout(function(){
			clearTimeout(ajaxTime);
			
			if(!/^get$/ig.test(s.type||"")){
				DWZ.showbg();
			}
			
			s.complete=function(){
				DWZ.hidebg();
			}
			
			if(!isReload){
				s.url=DWZ.toServiceUrl(s.url);
			}
			//==========超时弹出登陆筐===================================
			if(s.success){
				var _s=s;
				var _success = s.success;
				s.success = function(msg){
					if(typeof(msg)=="string"){
						_success(msg);
					}else if(msg.statusCode==DWZ.statusCode.timeout){
						//处理异步调用问题，把请求保存到一个数组中，请求完后删除						
						if(!top.ajaxList)top.ajaxList=new Array();
						top.ajaxList.push(_s);
						DWZ.hidebg();
						DWZ.login(function(){
							DWZ.reload();
						});
					}else if(msg.statusCode==DWZ.statusCode.ok){
						_success(msg);
					}else{
						DWZ.ajaxDone(msg);
					}
				}
			}
			$.ajax(s);
		},1);
	},
	get: function( url, data, callback, type, async ) {
		// shift arguments if data argument was omited
		async=!(data===false||callback===false||type===false||async===false);
		
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = null;
		}
		
		return DWZ.ajax({
			type: "GET",
			url: url,
			data: data,
			success: callback,
			dataType: type||"json",
			cache: false,
			async: async===false?false:true
		});
	},
	post: function( url, data, callback, type, async ) {
		// shift arguments if data argument was omited
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = {};
		}
		
		if(typeof(type)=="boolean"){
			async=type;
			type="json";
		}

		return DWZ.ajax({
			type: "POST",
			url: url,
			data: data,
			success: callback,
			dataType: type||"json",
			cache: false,
			async: async===false?false:true
		});
	},

	put:function(url, data, callback, type, async){
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = {};
		}
		
		if(typeof(type)=="boolean"){
			async=type;
			type="json";
		}

		return DWZ.ajax({
			type: "PUT",
			url: url,
			data: data,
			success: callback,
			dataType: type||"json",
			cache: false,
			async: async===false?false:true
		});
	},
	
	del:function( url, data, callback, type, async){
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = {};
		}
		
		if(typeof(type)=="boolean"){
			async=type;
			type="json";
		}

		return DWZ.ajax({
			type: "DELETE",
			url: url,
			data: data,
			success: callback,
			dataType: type||"json",
			cache: false,
			async: async===false?false:true
		});
	},
	/**
	 * 增加树节点
	 */
	addTree:function(ID,children){
		if(!ID||!children) return;
		
		var ul;
		if(typeof(ID)=="string"){
			ul=$("#"+ID);
			ul.html("");
		}else{
			if(ID[0].tagName=="UL"){
				ul=ID;
			}else{
				ul=$("<ul></ul>");
				ul.appendTo(ID);
			}
		}
		var p=ul.parents("ul");
		var level = p.length==0?0:(parseInt(p.attr("level")||0)+1)
		ul.attr("level",level);
		
		var tmp = ul.hasClass("tree")?ul.prev().html():ul.parents(".tree").prev().html();
		
		function addItem(item){
			var entity=item.sign_info?item.sign_info.name:(ul.attr("entity")||ul.parents("ul[entity]").attr("entity"));
			if(entity)item.entity=entity;
			/*
			var row=tmp.replace(/\$\{category_id}/ig,item.category_id)
					.replace(/\$\{name}/ig,item.name)
					.replace(/\$\{entity}/ig,entity);
			*/
			var row=tmp.bind(item).replace(/\$?\{(.)*?}/ig,"");
			
			row=$(row).data("item",item);
			
			var a=row.find("a");
			if(item.target)
				a.attr("target",item.target).attr("rel","category"+item.category_id);
			
			/*
			if(item.sign==undefined){
				a.attr("url",item.url||(item.keyword?DWZ.toServiceUrl("/management/page/"+item.keyword):""));
			}
			*/
			
			if(item.url) a.attr("url",item.url);
			
			//.text(item.name);
			row.appendTo(ul);
			if(item.children&&item.children.length>0){
				DWZ.addTree(row,item.children);
			}else if(item.r-item.l>1 || item.children_count>0){
				var action=row.parents("ul[action]").attr("action");
				$("<ul level="+(level+1)+"><li><a>请稍后...</a></li></ul>")
				.attr("action",action)
				.attr("category_id",item.category_id)
				.attr("loaded",false)
				.appendTo(row);
			}
		}
		
		if(children.length>0){
			$.each(children,function(i,item){
				addItem(item);
			})
		}else if(children.name){
			addItem(children);
		}
	},
	getPageContent:function(dom){
		return dom.parents(".pageContent");
//		var p=dom,i=0;
//		do{
//			if(p.hasClass("pageContent")) return p;
//			if(p==p.parent()) return;
//		}while((p=p.parent())&&i++<50)
	},
	loadPageContent:function(dom){
		var pageContent=DWZ.getPageContent(dom);
		$("table.list",pageContent).removeAttr("loaded");
		
		initUI(pageContent);
	}
};


(function($){
	// DWZ set regional
	$.setRegional = function(key, value){
		if (!$.regional) $.regional = {};
		$.regional[key] = value;
	};
	
	$.fn.extend({
		loadUrl: function(url,data,callback){
			if($.isFunction(data)){
				callback=data;
				data=null;
			}
			var $this = $(this);
			if ($.fn.xheditor) {
				$("textarea.editor", $this).xheditor(false);
			}
			
			$.ajax({
				type: 'GET',
				url: url,
				cache: false,
				dataType: "html",
				data: data,
				success: function(html){
					var json = DWZ.jsonEval(html);
					if (json.statusCode==DWZ.statusCode.timeout){
						alertMsg.error(DWZ.msg("sessionTimout"), {okCall:function(){
							DWZ.loadLogin();
						}});
					} if (json.statusCode==DWZ.statusCode.error){
						if (json.message) alertMsg.error(json.message);
					} else {
						var d=DWZ.param( data, url.substr(url.indexOf("?")+1))||{};
						$.each(d,function(k,v){
							html=html.replace(new RegExp("{"+k+"}","g"),function($1,$2,$3){
								if($3.substring($2-1,$2)=="$"){
									return $1;
								}
								return v;
							})
						});
						
						$this.html(html).jBind().initUI();

						if ($.isFunction(callback)) callback();
					}
				},
				error: DWZ.ajaxError
			});
		},
		initUI: function(){
			return this.each(function(){
				if($.isFunction(initUI)) initUI(this);
			});
		},
		//绑定表格数据
		jBinds:function(callback){
			this.each(function(){
				
			 	var table = $(this);
			 	if(!table.find(">tbody.list").attr("action")) return;
			 	
			 	if(table.attr("loaded")) return;
			 	table.attr("loaded",true);
			 	var pagination=table.next("div.panelBar").find("div.pagination");
			 	if(!pagination || pagination.length==0)
			 		pagination=table.parent().next("div.panelBar").find("div.pagination");
			 	if(pagination && pagination.length>0){
			 		pagination.attr("currentPage",1).data("table",table);
			 	}
			 	
			 	var subfields=table.find(">tbody.list").attr("subtotal");
			 	if(subfields) subfields=subfields.split(",");
			 	
			 	table.jLoad=function(){
			 		DWZ.showbg();
			 		var tmp = $(">tbody.templet",this);
			 		var tmplet=tmp.html();
			 		var formats={};
			 		tmp.find("[format]").each(function(){
			 			var $this=$(this);
			 			if($this.attr("format")){
			 				formats[$this.attr("name")||$this.attr("field")]=$this.attr("format");
			 			}
			 		})
			 		
			 		var loading = '<tr><td colspan="'+$(">thead>tr>th",this).length+'" align="center" style="padding: 3px;color:red;">数据加载中，请稍后...</td></tr>';
				 	var list=$(">tbody.list",this);//.html(loading);
				 	if(list.children().length==0)list.html(loading);
				 	var url=list.attr("action");
				 	
				 	if(!url||!url.isFinishedTm()){
				 		DWZ.hidebg();
				 		return;
				 	}
				 	
				 	var subtotal={};
				 	$.each(subfields||{},function(i,v){
				 		subtotal[v]=0;
				 	})

//				 	var pagination=getPagination();
				 	var param=$.extend({},$("tbody.list",table).data("param"),{
						pagesize:parseInt(pagination.attr("numPerPage")||20),
						pageno:parseInt(pagination.attr("currentPage")||1)
				 	});
				 	
				 	DWZ.get(url,param,function(json){
				 		if(!json) return;
				 		var data=json.result||[];
				 		if(data.length==undefined) data= new Array(data);
				 		var html=[];
				 		if(data.length==0){
				 			html.push("<tr class='nodate'><td align='center' colspan="+table[0].rows.item(1).cells.length+" style='color:red;'>无相关数据！</td></tr>");
				 		}
				 		else if(!(data instanceof Array)){
			 				html.push("<tr class='nodate'><td align='center' colspan="+table[0].rows.item(1).cells.length+" style='color:red;'>"+data+"</td></tr>");
			 			}
				 		else{
					 		for(var i=0;i<data.length;i++){
					 			var row=tmplet;
					 			var item=data[i];
					 			$.each(subtotal,function(k,v){
					 				if(typeof(item[k])=="number")subtotal[k]+=item[k];
					 			})
					 			$.each(formats,function(k,v){
					 				if(typeof(item[k])=="number") item[k]=item[k].format(v);
					 			})
					 			row=row.bind(item,true);
					 			
					 			html.push(row.replace(/\$\{num}/ig,i+1));
					 		}
					 		if(subfields){
					 			$.each(formats,function(k,v){
					 				if(typeof(subtotal[k])=="number") subtotal[k]=subtotal[k].format(v);
					 			})
					 			var $sfields = function(){
					 				return "[field="+subfields.join("],[field=")+"]"
					 			}();
					 			var $sub=$(tmplet.bind(subtotal,true).replace(/\$\{(.)*?}/ig,""));
					 			$sub.children().not($sfields).html("");
					 			$sub.children().eq(1).text("小计：").css("text-align","right");
					 			$sub.addClass("subtotal");
					 			html.push($("<div></div>").append($sub).html());
					 		}
				 		}
				 		list.html(html.join(""));//.replace(/\$\{(.)*?}/ig,"''")
				 		$("img[path]",list).attr("src", function(){
				 			var path = $(this).attr("path");
				 			return /\$\{.*}/.test(path)?this.src:path;
				 		});
				 		if(callback)callback();
				 		
				 		//绑定分页
				 		if(pagination && pagination.length>0 && !isNaN(json.total)){
				 			pagination.attr("totalCount",json.total);
				 			pagination.pagination();
				 		}
				 		
				 		//table.attr("loaded",true);
				 		
				 		table.cssTable();
				 		initUI(table);
				 		$(">thead input[name=objectId]",table).removeAttr("checked");
				 		DWZ.hidebg();
				 	});
			 	};
			 	table.jLoad();
			})
		},
		/**
		 * 绑定单个数据的页面
		 */
		jBind:function(callback){
			return this.each(function(){
				var item=$(this);
				if(item.attr("loaded")) return;
				item.attr("loaded",true);
				
				if(item.find("table.list tbody.list[action]").length>0){
					item.find("table.list").jBinds();
				}else{
					item.jLoad=function(callback){
						var content=$(".pageFormContent",item);
						var url=content.attr("action");
						if(!url){
							if(callback)callback();
							return;
						}
						content.removeAttr("action");
						DWZ.get(url,function(json){
							if(!json) return;
					 		var data=json.result||{};
					 		
					 		var bind=content.attr("bind");
					 		if(bind){//调用自定义绑定方法
					 			var $bind = eval('(' + bind + ')');
								$bind(data,content);
					 		}else{//系统默认绑定方法
								var html=content.html();
								
								html=html.bind(data);//.replace(/\$\{(.)*?}/ig,"");
								content.html(html);
								$("img[path]",content).attr("src", function(){return $(this).attr("path")});
								//item.attr("loaded",true);
					 		}
							if(callback)callback();
						},false);
					}
					item.jLoad(function(){
						$("select[action]",item).jBindCombox();
					});
				}
			})
		},
		jBindCombox:function(){
			return this.each(function(){
				var sel=$(this);
				sel.html("");
				var datas=sel.attr("datas");
				if(datas){
					datas=datas.split(",");
					var def=sel.attr("defSelValue");
					$.each(datas,function(i,data){
						if(!data) return;
						var item = data.split("=");
						var v=item[0],t=item[1]||item[0];
						var op = new Option(t,v);
						sel[0].options.add(op);
						if(def==op.value||def==op.text) sel[0].selectedIndex=i;
					});
					if(sel.attr("onchange")) sel.change();	
					return;
				}
				
				var url=sel.attr("action");
				if(!url) return;
				sel.removeAttr("action");
				
				DWZ.get(url,function(json){
					if(!json) return;
					var data=json.result||[];
					
					var value=sel.attr("opValue");
					var text=sel.attr("opText");
					var def=sel.attr("defSelValue");
					if(value.indexOf("${")<0) value="${"+value+"}";
					if(text.indexOf("${")<0) text="${"+text+"}";
					$.each(data,function(i,data){
//						var opString="value:\""+value+"\",text:\""+text+"\"";
						try{
							var v = value.bind(data);
							var t = text.bind(data);
							var op = new Option(t,v);
							$(op).data("data",data);
							
							sel[0].options.add(op);
							if(def==op.value) sel[0].selectedIndex=i;
						}catch(e){}
					});
					if(sel.attr("onchange")) sel.change();				
				},false);
			})
		},
		/**
		 * adjust component inner reference box height
		 * @param {Object} refBox: reference box jQuery Obj
		 */
		layoutH: function($refBox){
			return this.each(function(){
				var $this = $(this);
				if (! $refBox) $refBox = ("dialog" == $this.attr("layoutType") && $.pdialog) ? $.pdialog.getCurrent().find(".dialogContent") : $("#container .tabsPageContent");
				var iRefH = $refBox.height();
				var iLayoutH = parseInt($this.attr("layoutH"));
				$this.height(iRefH - iLayoutH > 50 ? iRefH - iLayoutH : 50);
			});
		},
		hoverClass: function(className){
			var _className = className || "hover";
			return this.each(function(){
				$(this).hover(function(){
					$(this).addClass(_className);
				},function(){
					$(this).removeClass(_className);
				});
			});
		},
		focusClass: function(className){
			var _className = className || "textInputFocus";
			return this.each(function(){
				$(this).focus(function(){
					$(this).addClass(_className);
				}).blur(function(){
					$(this).removeClass(_className);
				});
			});
		},
		inputAlert: function(){
			return this.each(function(){
				
				var $this = $(this);
				
				function getAltBox(){
					return $this.parent().find("label.alt");
				}
				function altBoxCss(opacity){
					var position = $this.position();
					return {
						width:$this.width(),
						top:position.top+'px',
						left:position.left +'px',
						opacity:opacity || 1
					}
				}
				if (!$this.val() && getAltBox().size() < 1) {
					if (!$this.attr("id")) $this.attr("id", $this.attr("name") + "_" +Math.round(Math.random()*10000));
					$('<label class="alt" for="'+$this.attr("id")+'">'+$this.attr("alt")+'</label>').appendTo($this.parent()).css(altBoxCss(1));
				}
				$this.focus(function(){
					getAltBox().css(altBoxCss(0.3));
				}).blur(function(){
					if (!$(this).val()) getAltBox().show()//.css("opacity",1);
				}).keydown(function(){
					getAltBox().hide();
				});		
			});
		},
		isTag:function(tn) {
			if(!tn) return false;
			return $(this)[0].tagName.toLowerCase() == tn?true:false;
		}
	});
	
	/**
	 * 扩展String方法
	 */
	$.extend(String.prototype, {
		isPositiveInteger:function(){
			return (new RegExp(/^[1-9]\d*$/).test(this));
		},
		isInteger:function(){
			return (new RegExp(/^\d+$/).test(this));
		},
		isNumber: function(value, element) {
			return (new RegExp(/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/).test(this));
		},
		trim:function(){
			return this.replace(/(^\s*)|(\s*$)|\r|\n|　/g, "");
		},
		trans:function() {
			return this.replace(/&lt;/g, '<').replace(/&gt;/g,'>').replace(/&quot;/g, '"');
		},
		replaceAll:function(os, ns) {
			return this.replace(new RegExp(os,"gm"),ns);
		},
		replaceTm:function($data) {
			if (!$data) return this;
			return this.replace(RegExp("({[A-Za-z_]+[A-Za-z0-9_]*})","g"), function($1){
				return $data[$1.replace(/[{}]+/g, "")];
			});
		},
		replaceTmById:function(_box) {
			var $parent = _box || $(document);
			return this.replace(RegExp("({[A-Za-z_]+[A-Za-z0-9_]*})","g"), function($1){
				var $input = $parent.find("#"+$1.replace(/[{}]+/g, ""));
				return $input.size() > 0 ? $input.val() : $1;
			});
		},
		replaceTmByName:function(_box) {
			var $parent = _box || $(document);
			return this.replace(RegExp("({[A-Za-z_]+[A-Za-z0-9_]*})","g"), function($1){
				var $input = $parent.find("input[name="+$1.replace(/[{}]+/g, "")+"]");
				var val=[];
				$.each($input,function(){
					if(this.type=="checkbox"){
						if(this.checked)val.push(this.value);
					}else{
						val.push(this.value);
					}
				})
				return val.length>0?val.join("_"):$1;
			});
		},
		encodeHTML:function(){
			return this.replace(/[<>\"]/g,function(c){return {'<':'&lt;','>':'&gt;','"':'&quot;'}[c]});
		},
		decodeHTML:function(){
			return this.replaceAll("&lt;","<")
						.replaceAll("&gt;",">")
						.replaceAll('&quot;','"');
		},
		bind:function(data,encodeHTML){
			var $this=$.browser.msie?this.replace(/[<\s]\w+=\${.*?}/g, function($1){
				return $1.replace(/\${.*?}/,function($1){return '\"'+$1+'\"'});
			}):this.replace(/%7(B|D)/g,function(c){return {'%7B':'{','%7D':'}'}[c]});
			return $this.replace(/\${(.)*?}/g, function($1){
	 			try{
	 				var val;
	 				//如果data是一个数组，把数组的值赋给tmpData begin by dengjinye 20130413
	 				if(data.length > 0){
//	 					debugger;
	 					var tmpData = data[0];
	 					val=eval("(tmpData."+$1.replace(/[\${}]+/g, "")+")");
	 					
	 					//waiting to do 去特例化
	 					//如果val是一个Object，取Object里面的值，可能是车管特有的
	 					if(typeof(val)=="object"){
	 						val = val.value;
	 					}
	 				}
	 				//end by dengjinye 20130413
					
					else{
						val=eval("(data."+$1.replace(/[\${}]+/g, "")+")");
					}
					return val===null?"":val===undefined?$1:encodeHTML==true&&typeof(val)=="string"?val.encodeHTML():val;
				}catch(e){
					return $1;
				}
			}).replace(/= +/g,'="" ').bindCode(data).bindFn(data);
		},
		bindCode:function(data){
			return this.replace(/code=\"(.)*?\"/g, function($1){
	 			try{
					var val=eval("(new Function(\""+$1.replace(/code=\"|\"+/g,"")+"\").call())");
					return val==null?"":val;
				}catch(e){
					return $1+e.name;
				}
			});
		},
		bindFn:function(data){
			return this.replace(/\[fn\].*?\[\/fn\]/g,function($1){
				try{
					var fn = $1.replace(/\[\/?fn\]+/g, "").replace(/&gt;/g,">").replace(/&lt;/g,"<");
//					alert(fn);
					var val=eval("("+fn+")");
//					alert(val);
					return val==null?"":val;
				}catch(e){
					return $1;
				}
			});
		},
		isFinishedTm:function(){
			return !(new RegExp("{[A-Za-z_]+[A-Za-z0-9_]*}").test(this)); 
		},
		skipChar:function(ch) {
			if (!this || this.length===0) {return '';}
			if (this.charAt(0)===ch) {return this.substring(1).skipChar(ch);}
			return this;
		},
		isValidPwd:function() {
			return (new RegExp(/^([_]|[a-zA-Z0-9]){6,32}$/).test(this)); 
		},
		isValidMail:function(){
			return(new RegExp(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(this.trim()));
		},
		isSpaces:function() {
			for(var i=0; i<this.length; i+=1) {
				var ch = this.charAt(i);
				if (ch!=' '&& ch!="\n" && ch!="\t" && ch!="\r") {return false;}
			}
			return true;
		},
		isPhone:function() {
			return (new RegExp(/(^([0-9]{3,4}[-])?\d{3,8}(-\d{1,6})?$)|(^\([0-9]{3,4}\)\d{3,8}(\(\d{1,6}\))?$)|(^\d{3,8}$)/).test(this));
		},
		isUrl:function(){
			return /^(\w+:)?\/\/([^\/?#]+)/.test(this);
		},
		isExternalUrl:function(){
			return this.isUrl() && this.indexOf("://"+document.domain) == -1;
		},
		host:function(){
			var url=/^(\w+:)?\/\/([^\/?#]+)/.exec(this);
			return url?url[2]:url;
		}
	});
})(jQuery);

/** 
 * You can use this map like this:
 * var myMap = new Map();
 * myMap.put("key","value");
 * var key = myMap.get("key");
 * myMap.remove("key");
 */
function Map(){

	this.elements = new Array();
	
	this.size = function(){
		return this.elements.length;
	}
	
	this.isEmpty = function(){
		return (this.elements.length < 1);
	}
	
	this.clear = function(){
		this.elements = new Array();
	}
	
	this.put = function(_key, _value){
		this.remove(_key);
		this.elements.push({key: _key, value: _value});
	}
	
	this.remove = function(_key){
		try {
			for (i = 0; i < this.elements.length; i++) {
				if (this.elements[i].key == _key) {
					this.elements.splice(i, 1);
					return true;
				}
			}
		} catch (e) {
			return false;
		}
		return false;
	}
	
	this.get = function(_key){
		try {
			for (i = 0; i < this.elements.length; i++) {
				if (this.elements[i].key == _key) { return this.elements[i].value; }
			}
		} catch (e) {
			return null;
		}
	}
	
	this.element = function(_index){
		if (_index < 0 || _index >= this.elements.length) { return null; }
		return this.elements[_index];
	}
	
	this.containsKey = function(_key){
		try {
			for (i = 0; i < this.elements.length; i++) {
				if (this.elements[i].key == _key) {
					return true;
				}
			}
		} catch (e) {
			return false;
		}
		return false;
	}
	
	this.values = function(){
		var arr = new Array();
		for (i = 0; i < this.elements.length; i++) {
			arr.push(this.elements[i].value);
		}
		return arr;
	}
	
	this.keys = function(){
		var arr = new Array();
		for (i = 0; i < this.elements.length; i++) {
			arr.push(this.elements[i].key);
		}
		return arr;
	}
}
